package top.xzxsrq.web.download;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.extern.log4j.Log4j2;
import org.htmlunit.html.FrameWindow;
import top.xzxsrq.common.utils.FileUtilsZX;
import top.xzxsrq.common.utils.NumberUtilsZX;
import top.xzxsrq.utils.PathUtils;
import top.xzxsrq.utils.StringUtilsZX;
import top.xzxsrq.web.download.entity.CheckFile;
import top.xzxsrq.web.download.entity.PageInfo;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * 类似飞极速下载，也就是url是有规律的
 */
@Log4j2
public class SimilarFeiJiSuD extends FeiJiSuD {
    public boolean isDownloadPage(String pathUrl) {
        return true;
    }

    @Override
    public String getDownloadType() {
        return "类似飞极速下载";
    }

    public String getPageDownLoadName(List<FrameWindow> iframes) {
        return htmlUnits.getPage().getTitleText();
    }

    public void downloadPages(
            String saveDir, // 文件保存位置
            int videoStart, // 视频开始位置
            int videoEnd, // 视频结束位置
            int nameLength, // 名字的长度
            String templatePageUrl // 下载模板url http://m.feijisu36.com/zongyi/90182/${}.html
    ) throws InterruptedException, ExecutionException {
        int checkNumber = 3;
        int count = 0;
        while (checkNumber > 0) {
            boolean checkFileFullOk;
            List<Future<Void>> futures = new LinkedList<>();
            for (int i = videoStart; i <= videoEnd; i++) {
                String s = NumberUtilsZX.doHandleZero(i, nameLength);
                String systemPath = PathUtils.pathStandardization(saveDir + "/" + s + ".mp4");
                // 直接检查本地文件是否和记录值一样
                CheckFile checkFile1 = checkLocalFile(systemPath);
                if (checkFile1 != null) {
                    FileUtilsZX.deleteFile(systemPath);
                    continue;
                }
                SimilarFeiJiSuD.SimilarFeiJiSuDT feiJiSuDT = new SimilarFeiJiSuD.SimilarFeiJiSuDT();
                feiJiSuDT.setSystemPath(systemPath);
                feiJiSuDT.setFeiJiSuD(this);
                feiJiSuDT.setDownloadId(this.downloadTaskId);
                feiJiSuDT.setI(i);
                feiJiSuDT.setIsFirstDownloadPage(videoStart == i);
                feiJiSuDT.setTemplatePageUrl(templatePageUrl);
                feiJiSuDT.setDownloadType(this.getDownloadType());
                futures.add(DownloadManager.submit(feiJiSuDT));
            }
            // 阻塞主线程
            for (Future<Void> future : futures) {
                future.get();
            }
            log.info("{}:{}:检查完整性第{}次", getDownloadType(), downloadTaskId, ++count);
            // 检查下载完整性
            checkFileFullOk = checkDownloadFullOk();
            if (checkFileFullOk) {
                log.info("{}:{}:下载完整", getDownloadType(), downloadTaskId);
                break;
            }
            checkNumber--;
        }
        log.info("{}:{}：检查次数{}：系统设置检查次数：{}：完整性：{}", getDownloadType(), downloadTaskId, count, checkNumber, checkDownloadFullOk());
    }

    @EqualsAndHashCode(callSuper = true)
    @Data
    public static class SimilarFeiJiSuDT extends FeiJiSuDT {
        public void overCall() throws IOException, InterruptedException {
            if (this.isCanStop()) {
                this.destroy();
                return;
            }
            CheckFile checkFile = new CheckFile();
            checkFile.setSystemPath(systemPath);
            CheckFile httpPathBySystemPath = feiJiSuD.getCheckFileBySystemPath(systemPath);
            String feiJiSuM3U8Url;
            int loop = isFirstDownloadPage ? 1 : 0; // 首页就是要多循环一次
            boolean breakPageQueryList = false;
            do {
                if (this.isCanStop()) {
                    this.destroy();
                    return;
                }
                if (this.isCanStop()) {
                    this.destroy();
                    return;
                }
                // 已经初始化且只有第一个页面需要判断不能重新使用第一个参数进行爬取页面
                if (isFirstDownloadPage) {
                    continue;
                }
                // 一个页面尝试3次
                for (int j = 0; j < 3; j++) {
                    if (this.isCanStop()) {
                        this.destroy();
                        return;
                    }
                    if (openPage(httpPathBySystemPath)) {
                        String pathUrl = StringUtilsZX.strFormat(templatePageUrl, String.valueOf(i));
                        checkFile.setDownloadPageUrl(pathUrl);
                        PageInfo pageInfo = feiJiSuD.getPageInfo(pathUrl, this, new String[]{".mp4", ".m3u8"}, false);
                        if (this.isCanStop()) {
                            this.destroy();
                            return;
                        }
                        feiJiSuM3U8Url = pageInfo.getDownloadUrl();
                        checkFile.setDownloadName(pageInfo.getDownloadName());
                    } else {
                        feiJiSuM3U8Url = httpPathBySystemPath.getDownloadUrl();
                        checkFile.setDownloadName(httpPathBySystemPath.getDownloadName());
                        checkFile.setDownloadPageUrl(httpPathBySystemPath.getDownloadPageUrl());
                    }
                    if (StringUtilsZX.isNotEmpty(feiJiSuM3U8Url)) {
                        log.info("feiJiSuM3U8Url = " + feiJiSuM3U8Url);
                        String[] https = feiJiSuM3U8Url.split("http"); // TODO 解析url
                        // 最后真正的下载地址
                        String m3u8Url = URLDecoder.decode("http" + https[https.length - 1], String.valueOf(Charset.defaultCharset()));
                        checkFile.setDownloadUrl(m3u8Url);
                        if (feiJiSuD.checkTimeIsOk(checkFile)) {
                            FileUtilsZX.deleteFile(systemPath);
                            breakPageQueryList = true;
                            break;
                        } else {
                            // 调用父级下载功能
                            PageInfo info = new PageInfo();
                            info.setDownloadType(this.getDownloadType());
                            info.setDownloadName(checkFile.getDownloadName());
                            info.setDownloadPageUrl(checkFile.getDownloadPageUrl());
                            info.setDownloadUrl(checkFile.getDownloadUrl());
                            setSavePath(checkFile.getLocalPath());
                            setPageInfo(info);
                            try {
                                downloadFunc();
                                FileUtilsZX.deleteFile(systemPath);
                                breakPageQueryList = true;
                                break;
                            } catch (Exception e) {
                                feiJiSuD.removeChecks(checkFile);
                                feiJiSuD.writeJSON();
                                Thread.sleep(2000);
                                throw e;
                            }
                        }
                    } else {
                        Thread.sleep(2000);
                    }
                }
                if (breakPageQueryList) {
                    break;
                }
                loop--;
            } while (loop == 0);
        }
    }
}
